{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 部署准备"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install --upgrade git+https://github.com/autodeployai/daas-client.git"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['TF_KERAS'] = '1'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from daas_client import DaasClient\n",
    "client = DaasClient('https://daas.autodeploy.ai', 'admin', 'password')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "project = '部署测试'\n",
    "if not client.project_exists(project):\n",
    "        client.create_project(project, 'deployment-test', '部署测试项目')\n",
    "client.set_project(project)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 默认部署Keras模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "import pandas as pd\n",
    "\n",
    "# Load the iris dataset (classification)\n",
    "iris = datasets.load_iris()\n",
    "iris_target_name = 'Species'\n",
    "iris_feature_names = iris.feature_names\n",
    "iris_df = pd.DataFrame(iris.data, columns=iris_feature_names)\n",
    "iris_df[iris_target_name] = iris.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense\n",
    "from keras.optimizers import Adam\n",
    "\n",
    "seed = 123456\n",
    "X, y = iris_df[iris_feature_names], iris_df[iris_target_name]\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=seed)\n",
    "\n",
    "# Train a multi-class model using Sequential\n",
    "model = Sequential()\n",
    "model.add(Dense(10, input_shape=(4,), activation='relu'))\n",
    "model.add(Dense(8, activation='relu'))\n",
    "model.add(Dense(6, activation='relu'))\n",
    "model.add(Dense(3, activation='softmax'))\n",
    "model.compile(Adam(lr=0.04), 'categorical_crossentropy', ['accuracy'])\n",
    "model.fit(X_train, pd.get_dummies(y_train).values, epochs=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pprint import pprint\n",
    "\n",
    "# Publish the built model into DaaS\n",
    "publish_resp = client.publish(model,\n",
    "                              name='keras-iris',\n",
    "                              mining_function='classification',\n",
    "                              x_test=X_test,\n",
    "                              y_test=y_test,\n",
    "                              description='A Keras classification model')\n",
    "pprint(publish_resp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_resp = client.test(publish_resp['model_name'], \n",
    "                        model_version=publish_resp['model_version'])\n",
    "pprint(test_resp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "response = requests.post(test_resp['endpoint_url'],\n",
    "                         headers={'Authorization': 'Bearer {token}'.format(token=test_resp['access_token'])},\n",
    "                         json=test_resp['payload'],\n",
    "                         verify=False)\n",
    "pprint(response.json())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "deploy_resp = client.deploy(model_name='keras-iris', \n",
    "                            deployment_name='keras-iris-svc',\n",
    "                            model_version=publish_resp['model_version'],\n",
    "                            replicas=1)\n",
    "pprint(deploy_resp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = requests.post(deploy_resp['endpoint_url'],\n",
    "                         headers={'Authorization': 'Bearer {token}'.format(token=deploy_resp['access_token'])},\n",
    "                         json=deploy_resp['payload'],\n",
    "                         verify=False)\n",
    "pprint(response.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 自定义部署Keras模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import absolute_import\n",
    "from __future__ import division\n",
    "from __future__ import print_function\n",
    "\n",
    "import numpy as np\n",
    "from tensorflow.keras.layers import Dense, Dropout, Input\n",
    "from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten\n",
    "from tensorflow.keras.models import Model\n",
    "from tensorflow.keras.datasets import mnist\n",
    "from tensorflow.keras.utils import to_categorical"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load MNIST dataset\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "# from sparse label to categorical\n",
    "num_labels = len(np.unique(y_train))\n",
    "y_train = to_categorical(y_train)\n",
    "y_test = to_categorical(y_test)\n",
    "\n",
    "# reshape and normalize input images\n",
    "image_size = x_train.shape[1]\n",
    "x_train = np.reshape(x_train,[-1, image_size, image_size, 1])\n",
    "x_test = np.reshape(x_test,[-1, image_size, image_size, 1])\n",
    "x_train = x_train.astype('float32') / 255\n",
    "x_test = x_test.astype('float32') / 255\n",
    "\n",
    "# network parameters\n",
    "input_shape = (image_size, image_size, 1)\n",
    "batch_size = 128\n",
    "kernel_size = 3\n",
    "filters = 64\n",
    "dropout = 0.3\n",
    "\n",
    "# use functional API to build cnn layers\n",
    "inputs = Input(shape=input_shape)\n",
    "y = Conv2D(filters=filters,\n",
    "           kernel_size=kernel_size,\n",
    "           activation='relu')(inputs)\n",
    "y = MaxPooling2D()(y)\n",
    "y = Conv2D(filters=filters,\n",
    "           kernel_size=kernel_size,\n",
    "           activation='relu')(y)\n",
    "y = MaxPooling2D()(y)\n",
    "y = Conv2D(filters=filters,\n",
    "           kernel_size=kernel_size,\n",
    "           activation='relu')(y)\n",
    "# image to vector before connecting to dense layer\n",
    "y = Flatten()(y)\n",
    "# dropout regularization\n",
    "y = Dropout(dropout)(y)\n",
    "outputs = Dense(num_labels, activation='softmax')(y)\n",
    "\n",
    "# build the model by supplying inputs/outputs\n",
    "model = Model(inputs=inputs, outputs=outputs)\n",
    "# network model in text\n",
    "model.summary()\n",
    "\n",
    "# classifier loss, Adam optimizer, classifier accuracy\n",
    "model.compile(loss='categorical_crossentropy',\n",
    "              optimizer='adam',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "# train the model with input images and labels\n",
    "model.fit(x_train,\n",
    "          y_train,\n",
    "          validation_data=(x_test, y_test),\n",
    "          epochs=3,\n",
    "          batch_size=batch_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pprint import pprint\n",
    "\n",
    "# Publish the built model into DaaS\n",
    "publish_resp = client.publish(model,\n",
    "                              name='keras-mnist',\n",
    "                              mining_function='classification',\n",
    "                              x_test=x_test,\n",
    "                              y_test=y_test,\n",
    "                              description='A tf.Keras classification model')\n",
    "pprint(publish_resp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过ONNX部署Keras模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import onnxmltools\n",
    "onnx_model = onnxmltools.convert_keras(model, model.name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "publish_resp = client.publish(onnx_model,\n",
    "                              name='keras-mnist-onnx',\n",
    "                              mining_function='classification',\n",
    "                              x_test=x_test,\n",
    "                              y_test=y_test,\n",
    "                              description='A tf.Keras classification model in ONNX')\n",
    "pprint(publish_resp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
